function DesignSUR = convert2sur(Design, Group)
%CONVERT2SUR Convert a multivariate normal regression model into an SUR model.
% Convert a multivariate normal regression model into a seemingly-unrelated
% regression model with a specified grouping of the data series.
%
%	DesignSUR = convert2sur(Design, Group);
%
% Inputs:
%	Design - Either a matrix or a cell-array that depends upon the number of
%		data series NUMSERIES. If NUMSERIES = 1, then this function is
%		irrelevant and just returns the Design matrix. If NUMSERIES > 1, then
%		Design is a cell array with NUMSAMPLES cells, where each cell contains a
%		NUMSERIES x NUMPARAMS matrix of known values.
%	Group - Group contains information about how data series are to be grouped
%		with separate parameters for each group. Groups can be specified in two
%		way - either by series or by groups. In either case, there are NUMSERIES
%		series and NUMGROUPS groups with 1 <= NUMGROUPS <= NUMSERIES. To
%		identify groups by series, construct an index vector that has NUMSERIES
%		elements. Element i = 1, ... , NUMSERIES in the vector has the index
%		j = 1, ... , NUMGROUPS of the group of which series i is a member.
%		To identify groups by series, construct a cell array with NUMGROUPS
%		elements. Each cell corresponds to the indexes of the series that
%		populate a given group. See Notes below for examples.
%
% Outputs:
%	DesignSUR - Either a matrix or a cell-array that depends upon the value of
%		NumSeries. If NUMSERIES = 1, then DesignSUR = Design, which should be a
%		NUMSAMPLES x NUMPARAMS matrix. If NUMSERIES > 1 and there are NUMGROUPS
%		groups to be formed, then Design is a cell array with NUMSAMPLES cells,
%		where each cell contains a NUMSERIES x (NUMGROUPS * NUMPARAMS) matrix of
%		known values. The original collection of parameters that are common to
%		all series are duplicated to collections of parameters for each group.
%
% Notes:   
%	Example with 10 series and 3 groups and 2 model parameters. Suppose
%		Group 1 has series 1, 3, 4, 8
%		Group 2 has series 2, 6, 10
%		Group 3 has series 5, 7, 9
%	Either:
%		Group = [ 1, 2, 1, 1, 3, 2, 3, 1, 3, 2];
%	or
%		Group = cell(3,1);
%		Group{1} = [1, 3, 4, 8];
%		Group{2} = [2, 6, 10];
%		Group{3} = [5, 7, 9];
%	A regression with DesignSUR would have 3*2 = 6 model parameters.
%
%
% See also MVNRMLE, ECMMVNRMLE, ECMLSRMLE

%	Copyright 2005 The MathWorks, Inc.
%	$Revision: 1.1.6.2 $ $Date: 2005/12/12 23:16:03 $

if nargin < 1
	error('Finance:convert2sur:MissingInputArg', ...
		'Missing required input argument Design.');
end

if iscell(Design)
	[NumSeries, NumParams] = size(Design{1});
else
	warning('Finance:conver2sur:Unnecessary', ...
		'Only one series so SUR not necessary.');
	DesignSUR = Design;		% since only 1 series, SUR is that same
	return
end

NumSamples = size(Design,1);

if nargin < 2 || isempty(Group)
	GroupIndex = [1:NumSeries]';
	NumGroups = NumSeries;
elseif iscell(Group)
	NumGroups = max(size(Group));
	if NumGroups > NumSeries
		error('Finance:convert2sur:TooManyGroupCells', ...
			'Too many cells in Group cell array.');
	end
	
	Count = 0;
	GroupIndex = zeros(NumSeries,1);
	for i = 1:NumGroups
		SubGroup = Group{i}(:);
		Count = Count + size(SubGroup,1);
		if Count > NumSeries
			error('Finance:convert2sur:TooManyGroupIndices', ...
				'Too many indices in Group cell array starting with cell %d.',i);
		end
		GroupIndex(SubGroup) = i;
	end
else
	GroupIndex = Group(:);
	NumGroups = max(GroupIndex);
end	

% make sure full coverage of specified number of groups

SubGroup = sort(GroupIndex);
for i = 1:NumSeries
	if (i == 1) && (SubGroup(i) ~= 1)
		error('Finance:convert2sur:InvalidGroupIndex', ...
			'First group index not equal to 1.');
	elseif i > 1
		if (SubGroup(i) - SubGroup(i-1)) > 1
			error('Finance:convert2sur:MissingGroupIndex', ...
				'Missing group index %d.',SubGroup(i-1) + 1);
		end
	end
end

% Set up SUR model

NumParamsSUR = NumGroups * NumParams;

DesignSUR = cell(NumSamples, 1);
for k = 1:NumSamples
	H = Design{k};
	HSUR = zeros(NumSeries, NumParamsSUR);
	for i = 1:NumSeries
		Offset = (GroupIndex(i) - 1) * NumParams;
		HSUR(i,Offset+1:Offset+NumParams) = H(i,:);
	end
	DesignSUR{k} = HSUR;
end
